package supermarket;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

public class ProductManager {
	private List<ProductScraper<?,?,?>> scrapers;
	private ProductInterpreter interpreter;
	private ProductPriceFactory productPriceFactory;
	private ProductFactory productFactory;
	
	private Session session;
	public static void main(String[] args) {
		LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog"); 
		ProductManager pm = new ProductManager();
		pm.scrapeSupermarkets();
	}
	public ProductManager(){
		initializeScrapers();
		setInterpreter(new ProductInterpreter());
		setProductPriceFactory(new ProductPriceFactory());
		setProductFactory(new ProductFactory());
	}
	private void initializeScrapers(){
		scrapers = new ArrayList<ProductScraper<?,?,?>>();
		
		Distributor[] distributors = Distributor.values();
		for(int i = 0; i < distributors.length; i++){
			switch(distributors[i]){
				case CARREFOUR:
//					scrapers.add(new ProductScraperCarrefour());
					break;
				case DELHAIZE:
					scrapers.add(new ProductScraperDelhaize(this));
					break;
				default:
					
			}
		}
	}
	public void scrapeSupermarkets(){
		session = HibernateUtil.getSessionFactory().openSession();
		for(ProductScraper<?,?,?> scraper: scrapers){
			scraper.scrape();
		}
		session.close();
	}
	public void scrapeSupermarket(Distributor distributor){
		
	}
	
	public void processProductInput(String name, String brand, String externalReference, Distributor distributor){
		Product product = getProductFactory().createProduct(name, brand, externalReference, distributor);
		
		session.beginTransaction();
		session.save(product);
		
		session.getTransaction().commit();
	}
	public void processProductPriceInput(String externalReference, Distributor distributor, String amount, String currency, String quantity, String unit, String unitPrice, 
			String unitOfUnitPrice){
		float interpretedAmount = getInterpreter().interpretAmount(amount);
		Currency interpretedCurrency = getInterpreter().interpretCurrency(currency);
		
		float interpretedQuantity = getInterpreter().interpretQuantity(quantity);
		Unit interpretedUnit = getInterpreter().interpretUnit(unit);
		
		float interpretedUnitPrice = getInterpreter().interpretUnitPrice(unitPrice);
		Unit interpretedUnitOfUnitPrice = getInterpreter().interpretUnitOfUnitPrice(unitOfUnitPrice);
		
		ProductPrice productPrice = getProductPriceFactory().createProductPrice(externalReference, distributor, interpretedAmount, interpretedCurrency, interpretedQuantity, interpretedUnit, interpretedUnitPrice, interpretedUnitOfUnitPrice);	
				
		session.beginTransaction();
		int nrOfRegProducts = ((Number) session.createCriteria(Product.class).setProjection(Projections.rowCount()).add(Restrictions.eq("externalReference", externalReference)).uniqueResult()).intValue();
		if(nrOfRegProducts >= 1){
			session.save(productPrice);
			session.getTransaction().commit();
		}

	}

	public ProductInterpreter getInterpreter() {
		return interpreter;
	}

	public void setInterpreter(ProductInterpreter interpreter) {
		this.interpreter = interpreter;
	}
	public ProductPriceFactory getProductPriceFactory() {
		return productPriceFactory;
	}
	public void setProductPriceFactory(ProductPriceFactory productPriceFactory) {
		this.productPriceFactory = productPriceFactory;
	}
	public void setProductFactory(ProductFactory productFactory) {
		this.productFactory = productFactory;
	}
	public ProductFactory getProductFactory() {
		return productFactory;
	}
}
